package com.aliwo.controller;

import com.aliwo.config.WeChatConfig;
import com.aliwo.domain.User;
import com.aliwo.domain.VideoOrder;
import com.aliwo.model.ResultResponse;
import com.aliwo.service.UserService;
import com.aliwo.service.VideoOrderService;
import com.aliwo.utils.JWTUtils;
import com.aliwo.utils.WXPayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Map;
import java.util.SortedMap;

/**
 * .
 *
 * @author Xu Yayuan
 * @date 2021/10/27
 */
@RequestMapping("/api/v1/wechat")
@RestController
public class WechatController {

    @Autowired
    private WeChatConfig weChatConfig;

    @Autowired
    private UserService userService;

    @Autowired
    private VideoOrderService videoOrderService;

    /**
     * 拼装微信扫一扫登录url
     *http://localhost:8080/api/v1/wechat/login_url?accessPage=www.xdclass.net
     * @param accessPage 访问地址
     */
    @GetMapping("/login_url")
    public ResultResponse loginUrl(@RequestParam String accessPage) throws UnsupportedEncodingException {
        String redirectUrl = weChatConfig.getOpenRedirectUrl(); // 获取开发平台重定向地址
        String callbackUrl = URLEncoder.encode(redirectUrl, "GBK"); // 进行编码
        String qrcodeUrl = String.format(WeChatConfig.getOpenQrcodeUrl(), weChatConfig.getOpenAppid(), callbackUrl, accessPage);
        return ResultResponse.buildSuccess(qrcodeUrl);
    }


    /**
     * 微信扫码登录回调地址
     */
    @GetMapping("/user/callback")
    public void wechatUserCallback(@RequestParam(value = "code") String code,
                                   String state, HttpServletResponse response) {
        User user = userService.saveWeChatUser(code);
        if (null != user) {
            // 生成jwt
            String token = JWTUtils.geneJsonWebToken(user);
            // state 当前用户的页面地址，需要拼接 http://  这样才不会站内跳转
            try {
                response.sendRedirect(state + "?token=" + token + "&head_img="
                        + user.getHeadImg() + "&name=" + URLEncoder.encode(user.getName(), "UTF-8"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 微信支付回调
     */
    @RequestMapping("/order/callback")
    public void orderCallback(HttpServletRequest request, HttpServletResponse response) throws Exception {
        InputStream inputStream = request.getInputStream();
        //BufferedReader是包装设计模式，性能更搞
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
        StringBuffer sb = new StringBuffer();
        String line;
        while ((line = in.readLine()) != null) {
            sb.append(line);
        }
        in.close();
        inputStream.close();
        Map<String, String> callbackMap = WXPayUtil.xmlToMap(sb.toString());
        SortedMap<String, String> sortedMap = WXPayUtil.getSortedMap(callbackMap);

        //判断签名是否正确
        if (WXPayUtil.isCorrectSign(sortedMap, weChatConfig.getKey())) {
            if ("SUCCESS".equals(sortedMap.get("result_code"))) {
                String outTradeNo = sortedMap.get("out_trade_no");
                VideoOrder dbVideoOrder = videoOrderService.findByOutTradeNo(outTradeNo);
                if (dbVideoOrder != null && dbVideoOrder.getState() == 0) {  //判断逻辑看业务场景
                    VideoOrder videoOrder = new VideoOrder();
                    videoOrder.setOpenid(sortedMap.get("openid"));
                    videoOrder.setOutTradeNo(outTradeNo);
                    videoOrder.setNotifyTime((Timestamp) new Date());
                    videoOrder.setState(1);
                    int rows = videoOrderService.updateVideoOderByOutTradeNo(videoOrder);
                    if (rows == 1) { //通知微信订单处理成功
                        response.setContentType("text/xml");
                        response.getWriter().println("success");
                        return;
                    }
                }
            }
        }
        //都处理失败
        response.setContentType("text/xml");
        response.getWriter().println("fail");
    }


}
